const input = {
    "a": 1,
    "b[0]": 1,
    "b[1]": 2,
    "b[2].c": true,
    "b[3][0]": 3,
    "d.e": 2,
    "d.f.e.g": 3,
    "e.j": 222,
    "e.k[0]": 1,
    "e.k[1]": 2,
    "e.k[2]": 3,
    "e.k[3].d": 32,
    "josie": "so cool"
}

const output = {
    a: 1,
    b: [ 1, 2, { c: true }, [ 3 ] ],
    d: { e: 2, f: 3 },
    g: null,
    e: {j: 222, k: [1,2,3,{d:32}]},
    f: undefined,
    h: '',
    josie: 'so cool'
}
function unflatten(obj) {
    //? 非对象
    if (Object(obj) !== obj || Array.isArray(obj)) {
        return obj;
    }
    //? 结果数组
    var result = {};
    //? 分组正则表达式 第一组匹配除了.或[]的字符 第二组匹配[]里的数值
    var r = /\.?([^\.\[\]]+)|\[(\d+)\]/g;
    for (var prop in obj) {
        var matchs;
        var cur = result;
        //? p=""是为了第一次必然能新建[]或{}
        var p = "";
        //? 如果能匹配到 这里用循环是有可能有多个匹配项
        while (matchs = r.exec(prop)) {
        //? 先判断结果数据中有无 没有就添加空的数组或对象 有则进去继续添加
            cur = cur[p] || (cur[p] = matchs[2] ? [] : {});
        //? p为匹配到的字符或数值 这两个只能同时存在一个
            p = matchs[2] || matchs[1];
        }
        //? 跳出while循环后(此时cur已经在应该在的位置了) 加入结果数组 obj[prop]代表原始的值
        cur[p] = obj[prop];
    }
    return result[""] || result;
}
console.log(unflatten(input));
